<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Quartz任务管理系统</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet">
    <style>
        :root {
            --primary-color: #3498db;
            --success-color: #2ecc71;
            --warning-color: #f39c12;
            --danger-color: #e74c3c;
            --light-bg: #f8f9fa;
            --border-color: #dee2e6;
        }

        body {
            background-color: var(--light-bg);
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            color: #333;
        }

        .main-container {
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
            margin-top: 20px;
            padding: 0;
        }

        .card-header {
            background: linear-gradient(135deg, var(--primary-color), #2980b9);
            color: white;
            border-radius: 8px 8px 0 0 !important;
            padding: 15px 20px;
        }

        .status-badge {
            padding: 4px 10px;
            border-radius: 12px;
            font-size: 0.8rem;
            font-weight: 500;
        }

        .status-normal { background-color: var(--success-color); color: white; }
        .status-paused { background-color: var(--warning-color); color: white; }
        .status-error { background-color: var(--danger-color); color: white; }

        .btn-action {
            padding: 4px 8px;
            margin: 1px;
            border-radius: 4px;
            font-size: 0.8rem;
        }

        .loading-spinner {
            display: inline-block;
            width: 1rem;
            height: 1rem;
            border: 2px solid #f3f3f3;
            border-top: 2px solid #3498db;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
    <div class="container-fluid">
        <a class="navbar-brand" href="#">
            <i class="bi bi-clock me-2"></i>Quartz任务管理系统
        </a>
        <div class="d-flex">
            <button class="btn btn-outline-primary" type="button" onclick="loadJobs()">
                <i class="bi bi-arrow-clockwise"></i> 刷新
            </button>
        </div>
    </div>
</nav>

<div class="container-fluid mt-3">
    <div class="main-container">
        <div class="card-header">
            <h5 class="mb-0"><i class="bi bi-list-task me-2"></i>任务列表</h5>
        </div>
        <div class="table-responsive">
            <table class="table table-hover mb-0">
                <thead class="table-light">
                <tr>
                    <th>任务名称</th>
                    <th>任务组</th>
                    <th>执行类</th>
                    <th>Cron表达式</th>
                    <th>状态</th>
                    <th>上次执行</th>
                    <th>下次执行</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody id="jobTableBody">
                <tr>
                    <td colspan="8" class="text-center py-5">
                        <div class="loading-spinner me-2"></div>
                        加载中...
                    </td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
    // API基础路径 - 根据您的实际部署调整
    const API_BASE = '/sys/quartz';

    // 页面加载完成后自动加载任务列表
    document.addEventListener('DOMContentLoaded', function() {
        loadJobs();
    });

    // 显示加载状态
    function showLoading() {
        const tbody = document.getElementById('jobTableBody');
        tbody.innerHTML = `
                <tr>
                    <td colspan="8" class="text-center py-5">
                        <div class="loading-spinner me-2"></div>
                        加载中...
                    </td>
                </tr>`;
    }

    // 显示错误状态
    function showError(message) {
        const tbody = document.getElementById('jobTableBody');
        tbody.innerHTML = `
                <tr>
                    <td colspan="8" class="text-center py-5 text-danger">
                        <i class="bi bi-exclamation-triangle me-2"></i>
                        ${message}
                    </td>
                </tr>`;
    }

    // 加载任务列表
    async function loadJobs() {
        showLoading();

        try {
            const response = await fetch(`${API_BASE}/jobs`);
            const result = await response.json();

            if (result.success) {
                renderJobTable(result.data);
            } else {
                showError('获取任务列表失败: ' + (result.message || '未知错误'));
            }
        } catch (error) {
            console.error('API调用错误:', error);
            showError('网络请求失败，请检查后端服务是否正常运行');
        }
    }

    // 渲染任务表格
    function renderJobTable(jobs) {
        const tbody = document.getElementById('jobTableBody');

        if (!jobs || jobs.length === 0) {
            tbody.innerHTML = `
                    <tr>
                        <td colspan="8" class="text-center py-5 text-muted">
                            <i class="bi bi-inbox display-4 d-block mb-2"></i>
                            暂无任务数据
                        </td>
                    </tr>`;
            return;
        }

        tbody.innerHTML = '';

        jobs.forEach(job => {
            const row = document.createElement('tr');

            // 根据Quartz状态映射显示文本[7](@ref)
            const stateClass = getStatusClass(job.triggerState);
            const statusText = getStatusText(job.triggerState);

            row.innerHTML = `
                    <td class="fw-semibold">${job.jobName || 'N/A'}</td>
                    <td><span class="badge bg-secondary">${job.jobGroup || 'DEFAULT'}</span></td>
                    <td>${job.jobClass || 'N/A'}</td>
                    <td><code class="cron-expression">${job.cronExpression || 'N/A'}</code></td>
                    <td><span class="status-badge ${stateClass}">${statusText}</span></td>
                    <td class="text-muted">${formatDate(job.previousFireTime)}</td>
                    <td class="fw-semibold">${formatDate(job.nextFireTime)}</td>
                    <td>
                        <div class="btn-group btn-group-sm">
                            ${job.triggerState === 'PAUSED' ?
                `<button class="btn btn-success btn-action" onclick="resumeJob('${job.jobName}', '${job.jobGroup}')">
                                    <i class="bi bi-play-circle"></i> 恢复
                                </button>` :
                `<button class="btn btn-warning btn-action" onclick="pauseJob('${job.jobName}', '${job.jobGroup}')">
                                    <i class="bi bi-pause-circle"></i> 暂停
                                </button>`
            }
                            <button class="btn btn-info btn-action" onclick="triggerJob('${job.jobName}', '${job.jobGroup}')">
                                <i class="bi bi-lightning"></i> 执行
                            </button>
                        </div>
                    </td>
                `;
            tbody.appendChild(row);
        });
    }

    // 根据Quartz状态获取CSS类[7](@ref)
    function getStatusClass(status) {
        if (!status) return 'status-error';

        switch(status.toUpperCase()) {
            case 'NORMAL':
            case 'WAITING': return 'status-normal';
            case 'ACQUIRED': return 'status-normal';
            case 'EXECUTING': return 'status-normal';
            case 'PAUSED': return 'status-paused';
            case 'ERROR': return 'status-error';
            case 'BLOCKED': return 'status-error';
            case 'COMPLETE': return 'status-normal';
            default: return 'status-error';
        }
    }

    // 根据状态获取显示文本[7](@ref)
    function getStatusText(status) {
        if (!status) return '未知状态';

        switch(status.toUpperCase()) {
            case 'NORMAL':
            case 'WAITING': return '等待执行';
            case 'ACQUIRED': return '已获取';
            case 'EXECUTING': return '执行中';
            case 'PAUSED': return '已暂停';
            case 'ERROR': return '错误';
            case 'BLOCKED': return '已阻塞';
            case 'COMPLETE': return '已完成';
            default: return status;
        }
    }

    // 日期格式化
    function formatDate(dateString) {
        if (!dateString) return 'N/A';

        try {
            const date = new Date(dateString);
            if (isNaN(date.getTime())) {
                return '无效日期';
            }
            return date.toLocaleString('zh-CN');
        } catch (error) {
            return '格式错误';
        }
    }

    // 暂停任务
    async function pauseJob(jobName, jobGroup) {
        if (!confirm(`确定要暂停任务 ${jobName} 吗？`)) return;

        try {
            const response = await fetch(`${API_BASE}/pauseJob`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    jobName: jobName,
                    jobGroup: jobGroup
                })
            });

            const result = await response.json();

            if (result.success) {
                alert('任务已暂停');
                loadJobs(); // 刷新列表
            } else {
                alert('操作失败: ' + (result.message || '未知错误'));
            }
        } catch (error) {
            console.error('Error:', error);
            alert('网络请求失败');
        }
    }

    // 恢复任务
    async function resumeJob(jobName, jobGroup) {
        try {
            const response = await fetch(`${API_BASE}/resumeJob`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    jobName: jobName,
                    jobGroup: jobGroup
                })
            });

            const result = await response.json();

            if (result.success) {
                alert('任务已恢复');
                loadJobs(); // 刷新列表
            } else {
                alert('操作失败: ' + (result.message || '未知错误'));
            }
        } catch (error) {
            console.error('Error:', error);
            alert('网络请求失败');
        }
    }

    // 立即执行任务
    async function triggerJob(jobName, jobGroup) {
        try {
            const response = await fetch(`${API_BASE}/triggerJob`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    jobName: jobName,
                    jobGroup: jobGroup
                })
            });

            const result = await response.json();

            if (result.success) {
                alert('任务已触发执行');
            } else {
                alert('操作失败: ' + (result.message || '未知错误'));
            }
        } catch (error) {
            console.error('Error:', error);
            alert('网络请求失败');
        }
    }

    // 删除任务
    async function deleteJob(jobName, jobGroup) {
        if (!confirm(`确定要删除任务 ${jobName} 吗？此操作不可恢复！`)) return;

        try {
            const response = await fetch(`${API_BASE}/deleteJob`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    jobName: jobName,
                    jobGroup: jobGroup
                })
            });

            const result = await response.json();

            if (result.success) {
                alert('任务已删除');
                loadJobs(); // 刷新列表
            } else {
                alert('操作失败: ' + (result.message || '未知错误'));
            }
        } catch (error) {
            console.error('Error:', error);
            alert('网络请求失败');
        }
    }
</script>
</body>
</html>